/****************************************************
 * 													*
 * 					BanzaiP2P						*
 * 													*
 * Versione: 0.1.1									*
 * Autore: D'Annessa Marco							*
 * File: http.h										*
 ****************************************************/

#ifndef HTTP_H_
#define HTTP_H_


static char http_version[] 	= "HTTP/1.0";
static char http_CRLF[] 	= "\r\n";

enum{

	HTTP_STR_RSPN_CODE_200 = 0x00,
	HTTP_STR_RSPN_CODE_201,
	HTTP_STR_RSPN_CODE_202,
	HTTP_STR_RSPN_CODE_204,
	
	HTTP_STR_RSPN_CODE_301,
	HTTP_STR_RSPN_CODE_302,
	HTTP_STR_RSPN_CODE_304,
	
	HTTP_STR_RSPN_CODE_400,
	HTTP_STR_RSPN_CODE_401,
	HTTP_STR_RSPN_CODE_403,
	HTTP_STR_RSPN_CODE_404,
	
	HTTP_STR_RSPN_CODE_500,
	HTTP_STR_RSPN_CODE_501,
	HTTP_STR_RSPN_CODE_502,
	HTTP_STR_RSPN_CODE_503

};

static char *http_rspn_code_string[] =
{

 	"200",
	"201",
	"202",
	"204",
 	"301",
	"302",
	"304",
	"400",
	"401",
	"403",
	"404",
	"500",
	"501",
	"502",
	"503"

};

static char *http_rspn_reason_string[] =
{
	"OK",
	"Created",
	"Accepted",
	"No Content",
	"Moved Permanently",
	"Moved Temporarily",
	"Not Modified",
	"Bad Request",
	"Unauthorized",
	"Forbidden",
	"Not Found",
	"Internal Server Error",
	"Not Implemented",
	"Bad Gateway",
	"Service Unavailable"
};


enum{
	HTTP_METHOD_CODE_GET = 0x00,
	HTTP_METHOD_CODE_HEAD,
	HTTP_METHOD_CODE_POST,
	
	HTTP_METHOD_CODE_THEP2P = 0x20,
		HTTP_METHOD_CODE_CONNECT,
		HTTP_METHOD_CODE_DISCONNECT,
	
		HTTP_METHOD_CODE_PING,
		HTTP_METHOD_CODE_PONG,
	
		HTTP_METHOD_CODE_QUERY,
		HTTP_METHOD_CODE_QUERYHIT,
	
		HTTP_METHOD_CODE_PEERFILELIST
	
};

enum{
	HTTP_STR_RQST_METH_GET = 0x00,
	HTTP_STR_RQST_METH_HEAD,
	HTTP_STR_RQST_METH_POST,
	HTTP_STR_RQST_METH_THEP2P
/*	HTTP_STR_RQST_METH_CONNECT,
	HTTP_STR_RQST_METH_DISCONNECT,
	HTTP_STR_RQST_METH_PING,
	HTTP_STR_RQST_METH_PONG,
	HTTP_STR_RQST_METH_QUERY,
	HTTP_STR_RQST_METH_QUERYHIT,
	HTTP_STR_RQST_METH_PEERFILELIST*/
};

static char *http_rqst_method_string[] =
{
	"GET",
	"HEAD",
	"POST",
	"THEP2P"
/*	"CONNECT",
	"DISCONNECT",
	"PING",
	"PONG",
	"QUERY",
	"QUERYHIT",
	"PEERFILELIST"*/
};

enum{
	HTTP_STR_RQST_THEP2P_CONNECT = 0x00,
	HTTP_STR_RQST_THEP2P_DISCONNECT,
	HTTP_STR_RQST_THEP2P_PING,
	HTTP_STR_RQST_THEP2P_PONG,
	HTTP_STR_RQST_THEP2P_QUERY,
	HTTP_STR_RQST_THEP2P_QUERYHIT,
	HTTP_STR_RQST_THEP2P_PEERFILELIST
};

static char *http_rqst_thep2p_string[] =
{
	"Connect",
	"Disconnect",
	"Ping",
	"Pong",
	"Query",
	"Queryhit",
	"Peerfilelist"
};

/*
enum
{
	HTTP_STR_RSPN_METH_PONG = 0x00,
	HTTP_STR_RSPN_METH_QUERYHIT
};

static char *http_rspn_method_string[] =
{
	"PONG",
	"QUERYHIT"
};
*/

enum
{
	HTTP_STR_GEN_HEAD_DATE = 0x00,
	HTTP_STR_GEN_HEAD_PRAGMA
};

static char *http_gen_header_string[] =
{
 	"Date",
	"Pragma"
};

enum{
	HTTP_STR_RQST_HEAD_AUTH	= 0x00,
	HTTP_STR_RQST_HEAD_FROM,
	HTTP_STR_RQST_HEAD_MOD_SINCE,
	HTTP_STR_RQST_HEAD_REFERER,
	HTTP_STR_RQST_HEAD_USER_AGENT
};

static char *http_rqst_header_string[] =
{
 	"Authorization",
	"From",
	"If-Modified-Since",
	"Referer",
	"User-Agent"
};

enum{
	HTTP_STR_RSPN_HEAD_LOCATION	= 0x00,
	HTTP_STR_RSPN_HEAD_SERVER,
	HTTP_STR_RSPN_HEAD_WWWAUTH
};

static char *http_rspn_header_string[] =
{
 	"Location",
	"Server",
	"WWW-Authenticate"
};

enum {
	HTTP_STR_ENT_HEAD_ALLOW	= 0x00,
	HTTP_STR_ENT_HEAD_CONT_ENC,
	HTTP_STR_ENT_HEAD_CONT_LEN,
	HTTP_STR_ENT_HEAD_CONT_TYPE,
	HTTP_STR_ENT_HEAD_EXPIRES,
	HTTP_STR_ENT_HEAD_LAST_MOD,
	HTTP_STR_ENT_HEAD_HOPS,
	HTTP_STR_ENT_HEAD_TTL,
	HTTP_STR_ENT_HEAD_DATA_TYPE,
	HTTP_STR_ENT_HEAD_ID
};

static char *http_ent_header_string[] =
{
 	"Allow",
	"Content-Encoding",
	"Content-Length",
	"Content-Type",
	"Expires",
	"Last-Modified",
	"Hops",
	"Time-To-Live"
};

struct http_gen_header
{
	char date[128];
	char pragma[128];
};

struct http_rqst_header
{
	char auth[128];
	char from[128];
	char mod_since[128];
	char referer[128];
	char user_agent[128];	
};

struct http_rspn_header
{
	char location[128];
	char server[128];
	char www_auth[128];
};

struct http_ent_header
{
	char allow[128];
	char cont_enc[128];
	char cont_len[128];
	char cont_type[128];
	char expires[128];
	char last_modified[128];

	char hops[4];
	char TTL[4];
	
	char id[128]; //2^(16*8)
};

////////// Request //////////
struct http_rqst
{
	//"Method SP Request-URI SP HTTP-Version CRLF"
	char method[32];
	char uri[512];
	char version[9]; // "HTTP/X.X"
	
	short int method_code;
};

struct http_rqst_msg
{
	//Request
	char *rqst_line;
	struct http_rqst request;
		
	//General Header
	struct http_gen_header gen_header;
	
	//Request Header
	struct http_rqst_header rqst_header;
	
	//Entity Header
	struct http_ent_header ent_header;
	
	//Entity
	char *entity;
	
};

////////// Response //////////
struct http_rspn
{
	char version[9];
	char code[4];
	char reason[33];
};

struct http_rspn_msg
{
	char *status_line; // "HTTP/1.0 ### 'Reason'"
		
	struct http_rspn response;
	
	//General Header
	struct http_gen_header gen_header;
	
	//Response Header
	struct http_rspn_header rspn_header;
	
	//Entity Header
	struct http_ent_header ent_header;

	//Entity
	char *entity;
	
};


////////// Request Functions//////////
void http_rqst_msg_init(struct http_rqst_msg* msg, char *hops, char *TTL);

int http_send_rqst(int sd, struct http_rqst_msg* msg, struct http_rspn_msg* rspn);

int http_recv_rqst(int sd, struct http_rqst_msg* msg);

int http_parse_rqst_line(struct http_rqst* rqst, char *rqst_line);

int http_parse_rqst_opt(struct http_rqst_msg* msg, char *rqst_opt_line);


////////// Response Functions//////////
void http_rspn_msg_init(struct http_rspn_msg* msg, char *hops, char *TTL);

int http_parse_rspn_line(struct http_rspn* rspn, char *rspn_line);

int http_send_rspn(int sd, struct http_rspn_msg* msg);

int http_recv_rspn(int sd, struct http_rspn_msg* msg);

int http_parse_rspn_line(struct http_rspn* rspn, char *rspn_line);

int http_parse_rspn_opt(struct http_rspn_msg* msg, char *rspn_opt_line);


////////// General Functions//////////
short int http_method_code_get(struct http_rqst* rqst);


#endif /*HTTP_H_*/
